import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { TWEEN } from 'three/examples/jsm/libs/tween.module.min';
import $ from 'jquery';
import { threeExport } from './threeExport';
import { lightUtil } from './threeLightUtil';
import { cameraUtil } from './threeCameraUtil';
import { mouseUtil } from './threeMouseUtil';
import { buttonUtil } from './threeButtonUtil';
import { controlsUtil } from './threeControlsUtil';
//import { loaderModel } from "./threeLoadModel2";
import { threeGLBUtil } from './threeGlbUtil';
export function initThree(id) { 
    THREE.Cache.enabled = true;
    threeExport.element = document.getElementById(id);
    threeExport.width = threeExport.element.clientWidth;
    threeExport.height = threeExport.element.clientHeight;
    createGroup();
    //创建场景
    createScene();
    //创建摄像机
    createCamera();
    //创建灯光,白色环境光，光照强度为1
    createLight();
    createRenderer();
    createControls();
    createSkyBox();
  //   threeGLBUtil.url.map(item => {
  //    loaderModel(threeExport.scene,item);
  // })
    // let url = "static/girl.glb"
    // loaderModel(threeExport.scene,url);
   
}

function createGroup() {
    
}
function createScene() {
    threeExport.scene = new THREE.Scene();
    threeExport.scene.background = new THREE.Color(0,0,0);
}
function createCamera() {
    cameraUtil.camera = new THREE.PerspectiveCamera(cameraUtil.cameraFov,threeExport.width/threeExport.height,cameraUtil.cameraNear,cameraUtil.cameraFar);
    cameraUtil.camera.position.copy(cameraUtil.cameraPostion)
}

function createLight() {
    lightUtil.ambientLight = new THREE.AmbientLight(lightUtil.ambientLightColor,lightUtil.ambientLightIntensity);
    threeExport.scene.add(lightUtil.ambientLight);
    // lightUtil.directionalLight = new THREE.DirectionalLight( lightUtil.directionalLightColor, lightUtil.directionalLightIntensity );
    // lightUtil.directionalLight.position.copy(lightUtil.directionalLightPosition)
      const light1 = new THREE.DirectionalLight(0xffffff, 0.2)
      light1.position.set(0, 0, 100)
      threeExport.scene.add(light1)
      const light2 = new THREE.DirectionalLight(0xffffff, 0.2)
      light2.position.set(0, 0, -100)
      threeExport.scene.add(light2)
      const light3 = new THREE.DirectionalLight(0xffffff, 0.2)
      light3.position.set(100, 0, 0)
      threeExport.scene.add(light3)
      const light4 = new THREE.DirectionalLight(0xffffff, 0.2)
      light4.position.set(-100, 0, 0)
      threeExport.scene.add(light4)

      const light5 = new THREE.DirectionalLight(0xffffff, 0.2)
      light5.position.set(0, 100, 0)
      threeExport.scene.add(light5)
      const light6 = new THREE.DirectionalLight(0xffffff, 0.2)
      light6.position.set(50, 100, 0)
      threeExport.scene.add(light6)
      const light7 = new THREE.DirectionalLight(0xffffff, 0.2)
      light7.position.set(0, 100, 50)
      threeExport.scene.add(light7)
      const light8 = new THREE.DirectionalLight(0xffffff, 0.2)
      light8.position.set(0, 100, -50)
      threeExport.scene.add(light8)
      const light9 = new THREE.DirectionalLight(0xffffff, 0.2)
      light9.position.set(-50, 100, 0)
      threeExport.scene.add(light9)
   // threeExport.scene.add( lightUtil.directionalLight );

}
function createRenderer() {
    threeExport.renderer = new THREE.WebGLRenderer({
        precision:'highp',
        alpha:true,
        antialias: true,
        // antialias: true,
		// logarithmicDepthBuffer: true,
    });
    threeExport.renderer.setPixelRatio( window.devicePixelRatio );
    threeExport.renderer.shadowMap.enabled  = true;
    threeExport.renderer.autoClear = true;
    threeExport.renderer.outputEncoding = THREE.sRGBEncoding;//調整色彩飽和度
    // renderer.physicallyCorrectLights = false;
    // renderer.toneMappingExposure = 0.1;
    threeExport.renderer.setSize(threeExport.width,threeExport.height);
    threeExport.element.appendChild(threeExport.renderer.domElement);
    threeExport.element.addEventListener('pointermove', mouseMove, false);
    threeExport.element.addEventListener('pointerup', mouseUp, false);
    threeExport.element.addEventListener('pointerdown', mouseDown, false);
}

function mouseMove() {
    let clientX = window.event.clientX;
    let clientY = window.event.clientY;
    let left = threeExport.element.getBoundingClientRect().left;
    let top = threeExport.element.getBoundingClientRect().top;
    let offsetWidth = threeExport.element.offsetWidth;
    let offsetHeight = threeExport.element.offsetHeight;
    mouseUtil.mouse.x = ((clientX - left) / offsetWidth) * 2 - 1;
    mouseUtil.mouse.y = -((clientY - top) / offsetHeight) * 2 + 1;
    document.body.style.cursor = 'default';
    threeExport.raycaster = new THREE.Raycaster();
    threeExport.raycaster.setFromCamera(mouseUtil.mouse, cameraUtil.camera);
}
function mouseUp() {
    let button = window.event.button;
    let clientX = window.event.clientX;
    let clientY = window.event.clientY;
    if (button == buttonUtil.buttonLeft) {
        if (clientX - mouseUtil.mouseClick.x <= buttonUtil.mouseClickX && clientY - mouseUtil.mouseClick.y <= buttonUtil.mouseClickX && Date.now() - mouseUtil.mouseClickTime < buttonUtil.mouseClickTime) {
            threeExport.raycaster = new THREE.Raycaster();
            threeExport.raycaster.setFromCamera(mouseUtil.mouse, cameraUtil.camera);
            let intersects = threeExport.raycaster.intersectObjects(threeExport.scene.children);
            if (intersects.length > 0) {
                  //console.log(intersects[0].object.name);
                if (
                intersects[0].object.name.includes('Door') ||
                intersects[0].object.name.includes('Trunk')
                ) {
                   
                let doorName = intersects[0].object.name.split('_')[0]
                  let door = threeExport.scene.children.find(item => item.name.indexOf(doorName) != -1)
                  let door1 = door.children[0];
                if (door1 && door1.outer && door1.status) {
                    setupTweenDoor(door1, door1.status)
                }
                }
                if (intersects[0].object.name.includes('INT')) {
                controlsUtil.controls.autoRotate = false
                let INT = threeExport.scene.children.find(item => item.name === 'INT')
                    setupTweenCarIn(INT)
                }
            }
        }
    }else if (button == buttonUtil.buttonRight) {
        if (clientX - mouseUtil.mouseClick.x <= buttonUtil.mouseClickX && clientY - mouseUtil.mouseClick.y <= buttonUtil.mouseClickX && Date.now() - mouseUtil.mouseClickTime < buttonUtil.mouseClickTime) {
            threeExport.raycaster = new THREE.Raycaster();
            threeExport.raycaster.setFromCamera(mouseUtil.mouse, cameraUtil.camera);
        }
    }
}
let tweenCollection = {
  LBDoor: {
    tween: null,
    from: { value: null },
    to: { value: null }
  },
  RBDoor: {
    tween: null,
    from: { value: null },
    to: { value: null }
  },
  LFDoor: {
    tween: null,
    from: { value: null },
    to: { value: null }
  },
  RFDoor: {
    tween: null,
    from: { value: null },
    to: { value: null }
  },
  Trunk: {
    tween: null,
    from: { value: null },
    to: { value: null }
  }
}
const setupTweenDoor = (door, status) => {
  // 状态发生改变了
  //  console.log(22222,door, status);
     const { from, to } = door.rotateDirection[status]
    if (status == 'open') {
      door.status = 'close'
    }
    if (status == 'close') {
      door.status = 'open'
    }
    // TWEEN.removeAll()
     let lastLocation = null
     console.log(tweenCollection[door.name]);
    if (tweenCollection[door.name].tween) {
      lastLocation = { value: tweenCollection[door.name].from.value }
      tweenCollection[door.name].tween.stop()
    } else {
      lastLocation = { value: from.value }
  }
  console.log('lastLocation',lastLocation);
    tweenCollection[door.name].tween = new TWEEN.Tween(lastLocation)
      .to(to, 1000)
      .easing(TWEEN.Easing.Cubic.InOut)
      .onUpdate(function (lastLocation) {
        console.log('update', lastLocation);
        console.log('333333update',door.outer);
        door.outer.rotation[door.rotateDirection.rotateAxis] = THREE.MathUtils.degToRad(lastLocation.value)
        tweenCollection[door.name].from.value = lastLocation.value
      })
      .onComplete(() => {
        tweenCollection[door.name] = {
          tween: null,
          from: { value: null },
          to: { value: null }
        }
      })
      .start()
}
const setupTweenCarIn = model => {
    const { x: cx, y: cy, z: cz } = cameraUtil.camera.position
    const { x: tocx, y: tocy, z: tocz } = model.carInCameraPosition

    setupTweenCamera(
      { cx, cy, cz, ox: 0, oy: 0, oz: 0 },
      { cx: tocx, cy: tocy, cz: tocz, ox: 0, oy: tocy, oz: 0.1 }
    )

    
}
function setupTweenCamera(source, target) {
      const carTween = new TWEEN.Tween(source)
        .to(target, 2000)
        .easing(TWEEN.Easing.Quadratic.Out)
      carTween.onUpdate(function (that) {
        cameraUtil.camera.position.set(that.cx, that.cy, that.cz)
        controlsUtil.controls.target.set(that.ox, that.oy, that.oz)
      })
      carTween.start()
    }
function mouseDown() {
    let clientX = window.event.clientX;
    let clientY = window.event.clientY;
    mouseUtil.mouseClick.x = clientX;
    mouseUtil.mouseClick.y = clientY;
    mouseUtil.mouseClickTime = Date.now();
}
function createControls() {
    controlsUtil.controls = new OrbitControls(cameraUtil.camera, threeExport.renderer.domElement);
    controlsUtil.controls.enableDamping = true;
    controlsUtil.controls.object.position.copy(controlsUtil.controlsObjectPosition);
    controlsUtil.controls.target.copy(controlsUtil.controlsTarget);
}

function createSkyBox() {
    let urls = [
        "static/model/skybox2/px.png",
        "static/model/skybox2/nx.png",
        "static/model/skybox2/py.png",
        "static/model/skybox2/ny.png",
        "static/model/skybox2/pz.png",
        "static/model/skybox2/nz.png",   
    ];
    let geometry = new THREE.BoxGeometry(10, 10, 10);
    let boxMaterials = [];
    urls.map(item => {
        let texture = new THREE.TextureLoader().load(item);
        boxMaterials.push(new THREE.MeshBasicMaterial({ map: texture }))
        // if (item.indexOf("py.png") != -1 || item.indexOf("ny.png") != -1) {
        //     texture.rotation = Math.PI;
        //     texture.center = new THREE.Vector2(0.5,0.5)
        // }
    })
    const cube = new THREE.Mesh(geometry, boxMaterials);
    cube.geometry.scale(1,1,-1)
    threeExport.scene.add(cube)
    // const textureCube = new THREE.CubeTextureLoader().load( urls );
    // textureCube.format = THREE.RGBFormat;
    // textureCube.mapping = THREE.CubeReflectionMapping;

    //threeExport.scene.background = textureCube;
   // threeExport.scene.opacity = 0;
//    var cubeLoader = new THREE.CubeTextureLoader();
//     threeExport.scene.background = cubeLoader.load(urls);
//     threeExport.scene.opacity = 0;
}

export function render() {
    
    if(controlsUtil.controls){
        controlsUtil.controls.update();
    }
    // 这里为啥每次都要设置size？
   threeExport.renderer.setSize(threeExport.width, threeExport.height);
  
  TWEEN.update();
    threeExport.renderer.render(threeExport.scene,cameraUtil.camera);
    requestAnimationFrame(render);
}